<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  
  
  <link rel="shortcut icon" href="../../img/favicon.ico">
  <title>comp.h - COROS Documentation</title>
  <link rel="stylesheet" href="../../css/theme.css" />
  <link rel="stylesheet" href="../../css/theme_extra.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
  
  <script>
    // Current page data
    var mkdocs_page_name = "comp.h";
    var mkdocs_page_input_path = "reference/03_comp.md";
    var mkdocs_page_url = null;
  </script>
  
  <script src="../../js/jquery-2.1.1.min.js" defer></script>
  <script src="../../js/modernizr-2.8.3.min.js" defer></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
  <script>hljs.initHighlightingOnLoad();</script> 
  
</head>

<body class="wy-body-for-nav" role="document">

  <div class="wy-grid-for-nav">

    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
    <div class="wy-side-scroll">
      <div class="wy-side-nav-search">
        <a href="../.." class="icon icon-home"> COROS Documentation</a>
        <div role="search">
  <form id ="rtd-search-form" class="wy-form" action="../../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" title="Type search term here" />
  </form>
</div>
      </div>

      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../..">Home</a>
                    </li>
                </ul>
                <p class="caption"><span class="caption-text">About</span></p>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../../COPYRIGHT/">Copyright</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../../LICENSE/">License</a>
                    </li>
                </ul>
                <p class="caption"><span class="caption-text">The Beginner's Guide to:</span></p>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../../tutorials/01_getting_started/">Getting Started</a>
                    </li>
                </ul>
                <p class="caption"><span class="caption-text">The Hitchker's Guide to:</span></p>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../../guides/01_coroutines/">Coroutines</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../../guides/02_event_queues/">Event Queues</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../../guides/03_components/">Components</a>
                    </li>
                </ul>
                <p class="caption"><span class="caption-text">The Technocrat's Guide to:</span></p>
                <ul class="current">
                    <li class="toctree-l1"><a class="reference internal" href="../01_co/">co.h</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../02_evq/">evq.h</a>
                    </li>
                    <li class="toctree-l1 current"><a class="reference internal current" href="./">comp.h</a>
    <ul class="current">
    <li class="toctree-l2"><a class="reference internal" href="#kay-style-oop">Kay-style OOP</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#components">Components</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#component-structure">Component structure</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#data-types">Data types</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#comp_declarename">COMP_DECLARE(NAME)</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#extern-void-name_activatevoid">extern void &lt;NAME&gt;_activate(void);</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#extern-void-name_deactivatevoid">extern void &lt;NAME&gt;_deactivate(void);</a>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#extern-void-name_initevq_queue_t-q-void-data">extern void &lt;NAME&gt;_init(evq_queue_t q, void *data);</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#comp_definename-stack">COMP_DEFINE(NAME, STACK);</a>
        <ul>
    <li class="toctree-l3"><a class="reference internal" href="#comp-user-callbacks">COMP user callbacks</a>
        <ul>
    <li class="toctree-l4"><a class="reference internal" href="#static-void-name_pump_x_initvoid-data">static void NAME_pump_x_init(void *data);</a>
    </li>
    <li class="toctree-l4"><a class="reference internal" href="#static-void-name_pump_x_terminatevoid-data">static void NAME_pump_x_terminate(void *data);</a>
    </li>
    <li class="toctree-l4"><a class="reference internal" href="#static-comp_body_t-name_pump_x_bodyvoid-data">static comp_body_t NAME_pump_x_body(void *data);</a>
    </li>
        </ul>
    </li>
    <li class="toctree-l3"><a class="reference internal" href="#comp-utility-primitives">COMP utility primitives</a>
        <ul>
    <li class="toctree-l4"><a class="reference internal" href="#static-void-name_callvoid-data">static void *NAME_call(void *data);</a>
    </li>
    <li class="toctree-l4"><a class="reference internal" href="#static-void-name_delayconst-tick_ms-duration">static void NAME_delay(const tick_ms duration);</a>
    </li>
    <li class="toctree-l4"><a class="reference internal" href="#static-void-name_sendvoid-data">static void NAME_send(void *data);</a>
    </li>
    <li class="toctree-l4"><a class="reference internal" href="#static-void-name_signalvoid">static void NAME_signal(void);</a>
    </li>
    <li class="toctree-l4"><a class="reference internal" href="#static-void-name_yieldvoid">static void NAME_yield(void);</a>
    </li>
        </ul>
    </li>
        </ul>
    </li>
    </ul>
                    </li>
                </ul>
                <p class="caption"><span class="caption-text">The Technomancer's Guide to:</span></p>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../../architecture/01_coroutines/">Coroutines</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../../architecture/02_event_queues/">Event Queues</a>
                    </li>
                    <li class="toctree-l1"><a class="reference internal" href="../../architecture/03_porting/">Porting</a>
                    </li>
                </ul>
      </div>
    </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
        <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
        <a href="../..">COROS Documentation</a>
      </nav>

      
      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="breadcrumbs navigation">
  <ul class="wy-breadcrumbs">
    <li><a href="../..">Docs</a> &raquo;</li>
    
      
        
          <li>The Technocrat's Guide to: &raquo;</li>
        
      
    
    <li>comp.h</li>
    <li class="wy-breadcrumbs-aside">
      
    </li>
  </ul>
  
  <hr/>
</div>
          <div role="main">
            <div class="section">
              
                <h1 id="the-technocrats-guide-to-comph">The Technocrat's Guide to <code>comp.h</code></h1>
<p>COMP is a component system for COROS.  Unlike CO and EVQ, which are a strict API, COMP is more a designe guideline intended to be paired with CO and EVQ to provide a "Kay-style" OOP for embedded systems.  This is why it is provided in a single header file, consists mostly as a design essay, and provides some helper macros that will give a sane default implementation of COROS COMP components.</p>
<h2 id="kay-style-oop">Kay-style OOP</h2>
<p>In his later days, Alan Kay stressed that classes, inheritance, etc. were <em>not</em> what he was aiming for when he coined the term "object-oriented programming".  He did not envision the monstrosities that are C++, Java, C#, et al.  What Kay said he intended was that an "object" was an independent software entity that responded to "messages".  The fact that his language&mdash;Smalltalk&mdash;had things like inheritance and such was an implementation detail.</p>
<p>COMP is an attempt to go back to these foundational roots of OOP.  It is informed by Kay, some nods to realism, and has a healthy dollop of the Pi Calculus added.  What this means is that there are no inheritance trees in COMP (unless you find a way to add them yourself: COMP is opinionated, not a panopticon).  There are no externally-visible member variables, member functions, etc.  There is just independent islands of computation (which we will be calling "components") who receive messages and respond to them, built up from coroutines and events.</p>
<p>At least that's the exterior view.  As you will see there are nods to reality in COMP's design.</p>
<h2 id="components">Components</h2>
<p>A canonical component in COMP has the following pieces:</p>
<ol>
<li>A private event queue hooked into a parent queue.</li>
<li>A private coroutine that forms its "message pump".</li>
<li>A public API that gives a familiar function-calling interface to the coroutine/message system underlying the component.</li>
</ol>
<p>Not all components require all pieces of this.  A "heartbeat" component, for example, might not really need a coroutine or even an event queue. Whatever the case, however, the user should not be required to know what pieces a component has or does not have.  The implementation should be a black box.</p>
<h3 id="component-structure">Component structure</h3>
<p>A component is typically placed in a single <code>.c</code>/<code>.h</code> pair.  The <code>.h</code> file exposes the public interface of the component while the <code>.c</code> file provides its implementation.  A compliant component <em>must</em> expose the following functions in its public API:</p>
<p><code>&lt;component&gt;_init()</code>        &ndash; hook up the component to the queue tree and start its processing if applicable
<code>&lt;component&gt;_deactivate()</code>  &ndash; stop processing events
<code>&lt;component&gt;_activate()</code>    &ndash; start processing events again</p>
<p>A component <em>may</em> also expose any API it wishes.  This could be as  primitive as a single function to send messages plus a variety of message structures to fill for processing, or it could be as complicated as a set of functions that helpfully wrap such a single primitive.  (It is strongly recommended that the latter be used.)</p>
<p>Functions exposed by COMP components will fall into three broad types:</p>
<ol>
<li>Wrappers that send a message and return immediately (like event notifications).</li>
<li>Wrappers that send a message and wait for the operation to complete, possibly with a return value (like procedure or function calls).</li>
<li>Functions that manipulate static state in the component and return immediately without sending messages (usually checking or altering internal state).</li>
</ol>
<p>From the perspective of a component user, there should be no visible difference in <em>use</em> of these three types (though there will be clear differences in performance and behaviour).</p>
<p>To assist in making conformant functions, two macros are provided which are outlined below: one to declare the component (in the <code>.h</code> file) and one to define it (in the <code>.c</code> file).  These will be explained below.</p>
<h2 id="data-types">Data types</h2>
<p><code>typedef enum _comp_body_t { COMP_TERMINATE, COMP_CONTINUE, } comp_body_t;</code></p>
<blockquote>
<p>This enumeration is used in the message pump supplied by the default implementation macro to decide if a component is to continue operation or to terminate.  Usually the correct answer is <code>COMP_CONTINUE</code>.</p>
</blockquote>
<h2 id="comp_declarename"><code>COMP_DECLARE(NAME)</code></h2>
<p>This macro declares a component's three mandatory public functions.</p>
<p><code>NAME</code> (in)</p>
<blockquote>
<p>The name of the component, used as a prefix to the <code>*_activate/deactivate/init()</code> functions.  Thus a heartbeat component declared as <code>COMP_DECLARE(HB);</code> would have <code>HB_activate()</code>, <code>HB_deactivate()</code>, and <code>HB_init()</code> declared.</p>
</blockquote>
<h3 id="extern-void-name_activatevoid"><code>extern void &lt;NAME&gt;_activate(void);</code></h3>
<p>Inserts the component's event queue into the parent queue's chain, rendering the component live.  (Note that components are started live: this function is only useful if the component has first been deactivated.)</p>
<h3 id="extern-void-name_deactivatevoid"><code>extern void &lt;NAME&gt;_deactivate(void);</code></h3>
<p>Removes the component's event queue from the parent queue's chain, rendering the component inert, unable to be processed by the parent's queue.  (It's individual queue can still be manually processed, of course.)</p>
<h3 id="extern-void-name_initevq_queue_t-q-void-data"><code>extern void &lt;NAME&gt;_init(evq_queue_t q, void *data);</code></h3>
<p>Takes a component parent queue and a <code>void *</code> of initialization data to pass into the component's coroutine.  Inside the function a default component will build the component's private event queue, attach it to the parent queue, create the component's message processing coroutine (called its 'pump'), and then start the coroutine, passing in the provided data.</p>
<p><code>q</code> (in)</p>
<blockquote>
<p>The queue to which the component is subordinate.  Internally a private event queue is created and attached to the supplied parent.</p>
</blockquote>
<p><code>data</code> (in)</p>
<blockquote>
<p>In addition to a private event queue, a component has a paired coroutine ("pump").  This is created and then started, with <code>data</code> passed in as its initializer.</p>
</blockquote>
<h2 id="comp_definename-stack"><code>COMP_DEFINE(NAME, STACK);</code></h2>
<p>This macro does most of the heavy lifting for making a COROS component.  It provides an implementation of the three functions declared by <code>COMP_DECLARE()</code> and it also supplies some operation primitives useful for building APIs.</p>
<p><code>NAME</code> (in)</p>
<blockquote>
<p>The name of the component; must match the name given to <code>COMP_DECLARE()</code>.</p>
</blockquote>
<p><code>STACK</code> (in)</p>
<blockquote>
<p>The size (in <strong>elements</strong>: c.f. the <code>co.h</code> reference documentation for details) of the stack needed for the component's message pump coroutine.</p>
</blockquote>
<p>This macro supplies several additional useful functions, detailed below, but also requires the end-user to supply three callbacks.  First the callbacks:</p>
<h3 id="comp-user-callbacks">COMP user callbacks</h3>
<p>In general the supplied message pump looks something like this:</p>
<pre><code class="language-C">static void NAME_pump(void *data)
{
    NAME_pump_x_init(data);

    do
    {
        data = co_yield(data);
    }
    while (NAME_pump_x_body(data) == COMP_CONTINUE);

    NAME_pump_x_terminate(data);
}
</code></pre>
<p>The three callback points are:</p>
<hr />
<h4 id="static-void-name_pump_x_initvoid-data"><code>static void NAME_pump_x_init(void *data);</code></h4>
<p>Called when the component's coroutine starts.  A good point to initialize static data, acquire memory resources, set up hardware, set up any child components, etc.</p>
<p><code>data</code> (in)</p>
<blockquote>
<p>The initialization data passed into <code>NAME_init()</code>.</p>
</blockquote>
<hr />
<h4 id="static-void-name_pump_x_terminatevoid-data"><code>static void NAME_pump_x_terminate(void *data);</code></h4>
<p>Called when the main loop of the message pump has signalled that the component should end operations.  Useful to clean up memory resources, put hardware into a neutral state, etc.</p>
<p><code>data</code> (in)</p>
<blockquote>
<p>The last message data sent to the message pump (the one that caused the pump to terminate).</p>
</blockquote>
<hr />
<h4 id="static-comp_body_t-name_pump_x_bodyvoid-data"><code>static comp_body_t NAME_pump_x_body(void *data);</code></h4>
<p>This is the meat of the message pump.  After <code>NAME_pump_x_init()</code> is called, the message pump yields.  The return value of <code>co_yield()</code> is then passed to this callback (usually containing a pointer to a message structure or the like).  The body can take any action it likes (though it should frequently yield if there are long actions being taken) and then it returns either <code>COMP_CONTINUE</code> if the pump should continue for another round or <code>COMP_TERMINATE</code> if the component is shutting down.</p>
<p><code>data</code> (in)</p>
<blockquote>
<p>The message sent to the message pump (i.e. the return value of <code>co_yield()</code>.</p>
</blockquote>
<hr />
<h3 id="comp-utility-primitives">COMP utility primitives</h3>
<p>Several helpful primitive operations are provided to assist in the building of APIs in COROS.  These are:</p>
<hr />
<h4 id="static-void-name_callvoid-data"><code>static void *NAME_call(void *data);</code></h4>
<p>This supplied primitive will directly resume the component's coroutine, acting like a function call, bypassing the event queue for quicker response and easier return value handling.</p>
<p><code>data</code> (in)</p>
<blockquote>
<p>The "message" being "sent" by resuming the coroutine.</p>
</blockquote>
<p>The return value is whatever value the coroutine's yield passes.</p>
<hr />
<h4 id="static-void-name_delayconst-tick_ms-duration"><code>static void NAME_delay(const tick_ms duration);</code></h4>
<p>This primitive delays in a non-blocking way for a given time.</p>
<p><code>duration</code> (in)</p>
<blockquote>
<p>The number of milliseconds that the current thread should suspend before continuing.</p>
</blockquote>
<hr />
<h4 id="static-void-name_sendvoid-data"><code>static void NAME_send(void *data);</code></h4>
<p>This primitive sends, using <code>evq_resume_now()</code>, a message on the component's private queue to the component's private coroutine.</p>
<p><code>data</code> (in)</p>
<blockquote>
<p>The message to send.</p>
</blockquote>
<p>This can be viewed as a function call where you don't care about the result, like a void pointer.</p>
<hr />
<h4 id="static-void-name_signalvoid"><code>static void NAME_signal(void);</code></h4>
<p>This just sends a <code>NULL</code> message, used chiefly to keep an active object alive.  It is a simple wrapper around <code>NAME_send(NULL)</code>.</p>
<hr />
<h4 id="static-void-name_yieldvoid"><code>static void NAME_yield(void);</code></h4>
<p>This primitive will first signal the component, and then immediately yields to give up time to other processes that need work.</p>
<hr />
              
            </div>
          </div>
          <footer>
  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="../../architecture/01_coroutines/" class="btn btn-neutral float-right" title="Coroutines">Next <span class="icon icon-circle-arrow-right"></span></a>
      
      
        <a href="../02_evq/" class="btn btn-neutral" title="evq.h"><span class="icon icon-circle-arrow-left"></span> Previous</a>
      
    </div>
  

  <hr/>

  <div role="contentinfo">
    <!-- Copyright etc -->
    
  </div>

  Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
      
        </div>
      </div>

    </section>

  </div>

  <div class="rst-versions" role="note" aria-label="versions">
    <span class="rst-current-version" data-toggle="rst-current-version">
      
      
        <span><a href="../02_evq/" style="color: #fcfcfc;">&laquo; Previous</a></span>
      
      
        <span style="margin-left: 15px"><a href="../../architecture/01_coroutines/" style="color: #fcfcfc">Next &raquo;</a></span>
      
    </span>
</div>
    <script>var base_url = '../..';</script>
    <script src="../../js/theme.js" defer></script>
      <script src="../../search/main.js" defer></script>
    <script defer>
        window.onload = function () {
            SphinxRtdTheme.Navigation.enable(true);
        };
    </script>

</body>
</html>
